package com.suitbim.commandserver.commandserver.client;

import com.google.gson.Gson;
import com.suitbim.commandserver.commandserver.client.ifs.CommandClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.File;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

abstract class AbstractClient implements CommandClient {

    Gson gson;

    ThreadPoolExecutor threadPoolExecutor;

    RedisTemplate<String, String> redisTemplate;

    String taskQueueTopic;

    Logger log;

    public AbstractClient(Gson gson, ThreadPoolExecutor threadPoolExecutor, RedisTemplate<String, String> redisTemplate, String taskQueueTopic) {
        this.gson = gson;
        this.threadPoolExecutor = threadPoolExecutor;
        this.redisTemplate = redisTemplate;
        this.taskQueueTopic = taskQueueTopic;
        this.log = LoggerFactory.getLogger(this.getClass());
        start();
    }

    void start() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                log.info(taskQueueTopic + ":thread start");
                while (true) {
                    List<Object> objects;
                    try {
                        objects = redisTemplate.executePipelined(new RedisCallback<Object>() {
                            @Override
                            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                                return connection.bLPop(360000, taskQueueTopic.getBytes());
                            }
                        });
                    } catch (Exception e) {
                        continue;
                    }
                    String json = (String) ((List) objects.get(0)).get(1);
                    try {
                        log.info(getClientPath() + ":begin command execute");
                        boolean success = execute(json);
                        log.info(getClientPath() + ":command execute success:" + success);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        log.info(getClientPath() + ":handle command finish");
                    }

                }
            }
        };
        threadPoolExecutor.submit(runnable);
    }

    @Override
    public File currentFile(String command) {
        return currentFile(gson.fromJson(command, CommandClient.Command.class));
    }

    @Override
    public boolean execute(String command) {
        return execute(gson.fromJson(command, CommandClient.Command.class));
    }


}
